from flask import current_app, g
from flask_restful import Resource

from cache.statistic import UserArticleCountStorage, UserFollowingsCountStorage, UserFansCountStorage
from models import db
from models.user import User
from utils.decorators import set_db_to_write, login_required
from flask_restful.reqparse import RequestParser
from utils.parser import image_file
from utils.storage import upload_file
from cache.user import UserProfileCache


class PhotoResource(Resource):
    """
    头像上传接口
    """
    method_decorators = [login_required, set_db_to_write]

    def patch(self):
        # 解析参数
        parser = RequestParser()
        parser.add_argument('photo', location='files', required=True, type=image_file)
        args = parser.parse_args()

        # 获取到上传的二进制数据
        # f = request.files.get('photo')  # type: FileStorage
        # f.save()    # f.read()
        f = args.photo
        img_bytes = f.read()

        # 上传到七牛云
        try:
            file_name = upload_file(img_bytes)
        except BaseException as e:
            current_app.logger.error(e)
            return {'message': 'image upload failed'}, 500

        # 方式2: 设置更新标记, 可以并发更新, 缺点: 无法完全保证mysql和redis数据的一致性, 只是减小了不一致的概率
        # 更新前, 先对该数据对象设置排它锁
        current_app.redis_cluster.incr('user:{}:profile:update'.format(g.user_id), 1)
        # 为了防止无法解除标记, 给更新标记设置过期时间
        current_app.redis_cluster.expire('user:{}:profile:update'.format(g.user_id), 2)
        # 将头像的URL保存到数据库
        User.query.filter_by(id=g.user_id).update({'profile_photo': file_name})
        db.session.commit()
        # 删除该数据对象对应的缓存
        UserProfileCache(g.user_id).clear()
        # 更新完成, 删除数据对象的更新标记
        if current_app.redis_cluster.get('user:{}:profile:update'.format(g.user_id)) == 1:
            current_app.redis_cluster.delete('user:{}:profile:update'.format(g.user_id))

        # json返回头像URL
        return {"photo_url": current_app.config['QINIU_DOMAIN'] + file_name}


class CurrentUserProfileResource(Resource):
    """个人中心-获取用户信息"""
    method_decorators = [login_required]
    def get(self):
        print("-----------", g.user_id)
        # 判断user_id是否存在
        user_cache = UserProfileCache(g.user_id)
        if user_cache.exists():
            # 获取数据
            try:
                user_dict = user_cache.get()
                # 获取统计类的数据
                user_dict['art_count'] = UserArticleCountStorage.get(g.user_id)
                user_dict['followings_count'] = UserFollowingsCountStorage.get(g.user_id)
                user_dict['fans_count'] = UserFansCountStorage.get(g.user_id)

            except BaseException as e:
                print(e)
                return {'message': "server error"}, 500

            # json返回
            return user_dict

        else:  # 用户id有问题
            return {'message': 'Invalid user'}, 400
